﻿using System.Web.Mvc;
using Coleotrack.Common.Registration;
using Coleotrack.Controllers;
using Coleotrack.Models.Setup;
using Moq;
using NUnit.Framework;

namespace Coleotrack.Test.Controllers
{
    [TestFixture]
    public class SetupControllerTest : ConcernOf<SetupController>
    {
        private Mock<IDatabaseConnector> databaseConnector;
        public override void Setup()
        {
            databaseConnector = new Mock<IDatabaseConnector>();

            Sut = new SetupController(databaseConnector.Object);
            Sut.SetFakeControllerContext(false);
        }

        public override void Teardown()
        {
            
        }

        [Test]
        public void Get_should_return_index_view()
        {
            // Act
            ActionResult result = Sut.Index();

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }

        [Test]
        public void Get_should_return_database_view()
        {
            // Act
            ActionResult result = Sut.Database();

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }

        [Test]
        public void Post_should_redirect_to_database_if_viewmodel_is_not_valid()
        {
            // Arrange
            var databaseViewModel = new DatabaseViewModel();

            // Act
            ActionResult result = Sut.Database(databaseViewModel);

            // Assert
            Assert.IsInstanceOf<ViewResult>(result);
        }

        [Test]
        public void Post_should_redirect_to_database_if_viewmodel_is_valid()
        {
            // Arrange
            var databaseViewModel = new DatabaseViewModel();
            databaseViewModel.Host = "HOST";
            databaseViewModel.Database = "Database";
            databaseViewModel.IntegratedAuth = false;
            databaseViewModel.Username = "Username";
            databaseViewModel.Password = "Password";

            databaseConnector
                .Setup(x => x.ConnectionIsValid(
                    databaseViewModel.Host, 
                    databaseViewModel.IntegratedAuth, 
                    databaseViewModel.Username, 
                    databaseViewModel.Password, 
                    databaseViewModel.Database))
                .Returns(true);

            // Act
            ActionResult result = Sut.Database(databaseViewModel);

            // Assert
            Assert.IsInstanceOf<RedirectToRouteResult>(result);
            Assert.AreEqual("Authentication", ((RedirectToRouteResult)result).RouteValues["Action"]);
            Assert.AreEqual("Setup", ((RedirectToRouteResult)result).RouteValues["Controller"]);
        }

        [Test]
        public void Get_should_return_authentication_view()
        {
            // Act
            ActionResult result = Sut.Authentication();

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }

        [Test]
        public void Post_should_redirect_to_authentication_if_viewmodel_is_not_valid()
        {
            // Arrange
            var authenticationViewModel = new AuthenticationViewModel();

            // Act
            ActionResult result = Sut.Authentication(authenticationViewModel);

            // Assert
            Assert.IsInstanceOf<ViewResult>(result);
        }

        [Test]
        public void Post_should_redirect_to_authentication_if_viewmodel_is_valid()
        {
            // Arrange
            var authenticationViewModel = new AuthenticationViewModel();
            authenticationViewModel.Username = "Username";
            authenticationViewModel.Password = "password";
            authenticationViewModel.PasswordConfirmation = "password";
            authenticationViewModel.Email = "me@example.com";
            authenticationViewModel.Firstname = "firstname";
            authenticationViewModel.Lastname = "lastname";

            // Act
            ActionResult result = Sut.Authentication(authenticationViewModel);

            // Assert
            Assert.IsInstanceOf<RedirectToRouteResult>(result);
            Assert.AreEqual("Finish", ((RedirectToRouteResult)result).RouteValues["Action"]);
            Assert.AreEqual("Setup", ((RedirectToRouteResult)result).RouteValues["Controller"]);
        }

        [Test]
        public void Post_should_redirect_to_authentication_if_passwords_are_not_equal()
        {
            // Arrange
            var authenticationViewModel = new AuthenticationViewModel();
            authenticationViewModel.Username = "Username";
            authenticationViewModel.Password = "password";
            authenticationViewModel.PasswordConfirmation = "password2";
            authenticationViewModel.Email = "me@example.com";
            authenticationViewModel.Firstname = "firstname";
            authenticationViewModel.Lastname = "lastname";

            // Act
            ActionResult result = Sut.Authentication(authenticationViewModel);

            // Assert
            Assert.IsInstanceOf<ViewResult>(result);
        }

        [Test]
        public void Post_should_redirect_to_authentication_if_email_is_not_valid()
        {
            // Arrange
            var authenticationViewModel = new AuthenticationViewModel();
            authenticationViewModel.Username = "Username";
            authenticationViewModel.Password = "password";
            authenticationViewModel.PasswordConfirmation = "password";
            authenticationViewModel.Email = "...";
            authenticationViewModel.Firstname = "firstname";
            authenticationViewModel.Lastname = "lastname";

            // Act
            ActionResult result = Sut.Authentication(authenticationViewModel);

            // Assert
            Assert.IsInstanceOf<ViewResult>(result);
        }

        [Test]
        public void Get_should_return_finish_view()
        {
            // Act
            ActionResult result = Sut.Finish();

            // Assert
            Assert.IsInstanceOf(typeof(ViewResult), result);
        }
    }
}